package com.lac.component.controller;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.lac.component.dao.GoodsDao;
import com.lac.component.dao.GoodsSpuMapper;
import com.lac.component.model.Goods;
import com.lac.component.model.GoodsSpu;
import com.lac.component.model.MessageInfo;
import com.lac.component.model.User;
import com.lac.component.rabbitmq.MsgProducer;
import com.lac.component.rabbitmq.RabbitConfig;
import com.lac.component.service.UserService;
import com.lac.component.thread.ThreadPoolConfigExample;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;

@RestController
public class DemoController {



    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ConnectionFactory connectionFactory;

    @Autowired
    private RabbitConfig rabbitConfig;

    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private UserService userService;

    @GetMapping("/")
    public String getHello() {
        return "hello";
    }
    @GetMapping("/user/{string}")
    public String test(@PathVariable String string) {
        return "Hello Nacos :" + string;
    }
    @GetMapping("/danbing2226/{string}")
    public String test1(@PathVariable String string) {
        return "灰色天空 :" + string;
    }
    @GetMapping("/xiawanan/{str}")
    public String test2(@PathVariable String str) {
        return "夏婉安的歌曲:"+str;
    }
    @GetMapping("/huisetiankong/{str}")
    public String test3(@PathVariable String str) {
        return "听了无数遍:"+str;
    }

    @PostMapping("/fenshouyihou/{str}")
    public String test4(HttpSession session,@PathVariable String str){
        session.setAttribute("id",str);
        return  str;
    }

    @GetMapping("/xiahuashang")
    public String test5(HttpSession session){
        String str = (String) session.getAttribute("id");
        return  str;
    }

    @GetMapping("/rabbit")
    public  String send() throws Exception{

        String goodsId = "1";
        Random r = new Random(1);
        int i = r.nextInt(1000);
            MsgProducer producer = new MsgProducer(rabbitConfig.rabbitTemplate(connectionFactory));
//            System.out.println(redisTemplate.opsForValue().toString());
            Integer count = (Integer) redisTemplate.opsForValue().get(goodsId);
            if(count == 0){
//                System.out.println("没库存了");
                return "没库存了";
            }
            long kucun = redisTemplate.opsForValue().decrement(goodsId,i);
            if(kucun <0 ){
                count = (Integer) redisTemplate.opsForValue().get(goodsId);
                if(count != 0 && count < Integer.valueOf(i)){
                    redisTemplate.opsForValue().increment(goodsId,i);
//                    System.out.println("买多了再把库存还原");
                    return "买多了再把库存还原";
                }else if(count == 0){
                    redisTemplate.opsForValue().set(goodsId,0);
                    return "库存卖完了";
                }
//                System.out.println("redis库存:"+ redisTemplate.opsForValue().get(goodsId));
            }
            producer.sendMsg(goodsId,String.valueOf(i));
      return "下单成功";
    }

    // 发送延时消息
    @GetMapping("/sendDelayedMessage")
    public  String send1() {
        // x-delayed-type  延时消息的类型
        MsgProducer producer = new MsgProducer(rabbitConfig.rabbitTemplate(connectionFactory));
        producer.sendDelayedMessage("1");
        //  x-dead-letter-exchange 死信队列的交换机
        MsgProducer producer1 = new MsgProducer(rabbitConfig.rabbitTemplate(connectionFactory));
        producer1.sendDelayedMessage("1", 100);
        return "下单成功";
    }

    //发送消息
    @GetMapping("/sendMsgToTripleQueue")
    public String sendMsgToTripleQueue() {
        //这是我们将消息发给三个队列，来提高并发处理能力，查看消息处理结果
        for (int i = 1; i <= 3; i++) {
            MessageInfo message = new MessageInfo();
            message.setId(i);
            for (int j = 1; j <= 3; j++) {
                message.setId(i);
                message.setMessage("订单操作id：" + i + " 用户id：" + j);
                MsgProducer producer = new MsgProducer(rabbitConfig.rabbitTemplate(connectionFactory));
                if (j==1){
                    producer.convertAndSend("triple_exchange","triple-one", message);
                }
                if (j==2){
                    producer.convertAndSend("triple_exchange","triple-two", message);
                }
                if (j==3){
                    producer.convertAndSend("triple_exchange","triple-three", message);
                }
            }
        }
        return "消息发送成功";
    }
    //发送消息
//    @HasPermission("admin")
    @GetMapping("/sendMsg")
    public String sendMsg() {
        MsgProducer producer = new MsgProducer(rabbitConfig.rabbitTemplate(connectionFactory));
        for (int i = 1; i <= 3; i++) {
            MessageInfo message = new MessageInfo();
            message.setId(i);
            for (int j = 1; j <= 3; j++) {
                message.setId(i);
                message.setMessage("订单操作id：" + i + " 用户id：" + j);
                producer.sendMessage(message, "key" + j);
            }
        }
        return "消息发送成功";
    }
    @GetMapping("/getRBloomFilter")
    private  String  getRBloomFilter(String  str) {
        RBloomFilter<String> bloomFilter = redissonClient.getBloomFilter("myBloom");
        boolean element1 = bloomFilter.contains(str);
        return  element1==true?"存在":"不存在";
    }

    @GetMapping("/setRBloomFilter")
    private  String  setRBloomFilter(String  str) {
        RBloomFilter<String> bloomFilter = redissonClient.getBloomFilter("myBloom");
        boolean element1 = bloomFilter.add(str);
        bloomFilter.delete();
        return element1 == true ? "成功" : "失败";
    }

    @GetMapping("/task")
    public String task() throws InterruptedException {
        // 1. 准备数据
        int batchSize = 100; // 批量插入大小
        List<Goods> goodsList = ThreadPoolConfigExample.generateGoodsData(batchSize * 3); // 生成测试数据，这里是批量的3倍
        // 2. 配置线程池
        int threadPoolSize = 10; // 线程池大小，根据实际情况调整
//        ExecutorService executorService = Executors.newScheduledThreadPool(threadPoolSize);
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(6, 6,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(),
                new ThreadFactoryBuilder().setNameFormat("goodsTabCount-fixed-pool-%d").build());
        // 3. 批量插入
        long startTime = System.currentTimeMillis();
        int totalInsertedCount = 0;
        List<Future<Integer>> futures = new ArrayList<>();
        for (int i = 0; i < goodsList.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, goodsList.size());
            List<Goods> subList = goodsList.subList(i, endIndex);
            // 提交任务到线程池
            Future<Integer> future = executorService.submit( new ThreadPoolConfigExample.GoodsInsertTask(goodsDao, subList));
            futures.add(future);
        }
        // 4. 获取结果
        for (Future<Integer> future : futures) {
            try {
                totalInsertedCount += future.get(); // 获取插入成功的数量
            } catch (InterruptedException | ExecutionException e) {
                // 处理异常，例如记录日志
                e.printStackTrace();
            }
        }
        // 5. 关闭线程池 (重要)
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES); // 等待所有任务完成，最多 1 分钟
        Hashtable<String, String> map = new Hashtable<>();
        map.put("totalInsertedCount", String.valueOf(totalInsertedCount));
        long endTime = System.currentTimeMillis();
//        System.out.println("批量插入完成，总共插入 " + totalInsertedCount + " 条数据, 耗时 " + (endTime - startTime) + " 毫秒");
        return "task";
    }

    @GetMapping("/task1")
    public String task1() throws InterruptedException {
        // 1. 准备数据
        int batchSize = 100; // 批量插入大小
        List<Goods> goodsList = ThreadPoolConfigExample.generateGoodsData(batchSize * 3); // 生成测试数据，这里是批量的3倍
        // 2. 配置线程池
        int threadPoolSize = 10; // 线程池大小，根据实际情况调整
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(6, 6,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(),
                new ThreadFactoryBuilder().setNameFormat("goodsTabCount-fixed-pool-%d").build());
        // 3. 批量插入
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < goodsList.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, goodsList.size());
            List<Goods> subList = goodsList.subList(i, endIndex);
            // 提交任务到线程池
             executorService.submit( new ThreadPoolConfigExample.GoodsInsertTask1(goodsDao, subList));

        }
        // 5. 关闭线程池 (重要)
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES); // 等待所有任务完成，最多 1 分钟
        long endTime = System.currentTimeMillis();
//        System.out.println("批量插入完成，总共插入 "  + " 耗时 " + (endTime - startTime) + " 毫秒");
        return "task";
    }

    @GetMapping("/for")
    public String for1() {
        long startTime = System.currentTimeMillis();
        int totalInsertedCount = 0;
        int batchSize = 100; // 批量插入大小
        List<Goods> goodsList = ThreadPoolConfigExample.generateGoodsData(batchSize * 3); // 生成测试数据，这里是批量的3倍
        goodsList.forEach(goods -> {
            goodsDao.insertGoods(goods);
        });
        long endTime = System.currentTimeMillis();
//        System.out.println("批量插入完成，总共插入 " + totalInsertedCount + " 条数据, 耗时 " + (endTime - startTime) + " 毫秒");
        return "for1";
    }

    @GetMapping("/for2")
    public String for2() {
        // 1. 准备数据
        int batchSize = 100; // 批量插入大小
        List<Goods> goodsList = ThreadPoolConfigExample.generateGoodsData(batchSize * 3);
        // 创建调度池，核心线程数为2
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

        // 定时任务：5秒后开始，每隔3秒执行一次
        scheduler.scheduleAtFixedRate(() -> {
            int result = goodsDao.insertGoodsList(goodsList);

        }, 5, 3, TimeUnit.SECONDS);
        return "for2";
    }
    @GetMapping("/insertUser")
    public User insertUser() {
        User user1 = userService.saveUser();
        User user = userService.selectUser();
        return user;
    }


}
